<template>
  <div class="p-4">
    <!-- header -->
    <a-page-header
      style="background-color: white"
      :title="`${props.type == 'edit' ? '编辑' : '添加'}商品信息`"
      @back="handleBack"
    />
    <div style="background-color: white" class="p-4">
      <a-steps v-model:current="state.current" @change="handleChange">
        <a-step title="基本信息" />
        <a-step title="商品参数" />
        <a-step title="商品属性" />
        <a-step title="商品图片" />
        <a-step title="商品内容" />
      </a-steps>
      <!-- contain -->
      <div class="m-10">
        <!-- step 1 -->
        <BasicForm v-show="state.current == 0" @register="register" />
        <!-- step 2 -->
        <div v-show="state.current == 1">
          <attributeCheckbox
            v-for="item in state.productParameter"
            :key="item.attr_id"
            :attribute-item="item"
            @get-checkbox="getCheckbox"
          />
        </div>
        <!-- step 3 -->
        <BasicForm v-show="state.current == 2" @register="attributesRegister" />
        <!-- step 4 -->
        <div v-show="state.current == 3">
          <div class="mb-4">
            <a-alert
              message="因为图片删除功能未完善，所以编辑时请清空缓存图片再上传"
              type="info"
              show-icon
            />
          </div>
          <a-upload
            list-type="picture"
            v-model:file-list="state.fileList"
            :customRequest="handleAction"
            :remove="handleRemove"
            @preview="handlePreview"
          >
            <a-button>
              <UploadOutlined />
              点击上传
            </a-button>
          </a-upload>
        </div>
        <!-- step 5 -->
        <Tinymce
          v-show="state.current == 4"
          v-model="state.tinymce"
          width="100%"
          :showImageUpload="false"
        />
      </div>
      <!-- button -->
      <div class="flex justify-end">
        <a-button v-if="state.current != 0" class="mr-5" @click="setCurrent('pre')"
          >上一步</a-button
        >
        <a-button v-if="state.current != 4" type="primary" @click="setCurrent('next')"
          >下一步</a-button
        >
        <a-button v-if="state.current == 4" type="primary" @click="submitProduct">{{
          props.type == 'edit' ? '确认修改' : '添加商品'
        }}</a-button>
      </div>
    </div>
    <!-- picture preview -->
    <a-modal
      :visible="state.modelParams.previewVisible"
      :footer="null"
      width="100%"
      class="full-modal"
      :centered="true"
      @cancel="handleModelCancel"
    >
      <img
        alt="example"
        style="max-height: 100vh; padding: 50px; margin: 0 auto"
        :src="state.modelParams.previewImage"
      />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { UploadOutlined } from '@ant-design/icons-vue';
  import { message } from 'ant-design-vue';
  import { onMounted, reactive, ref, toRaw, watch } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import { Tinymce } from '/@/components/Tinymce/index';
  import { useShopGoodsStore } from '/@/store/modules/shopGoodsStore';
  import attributeCheckbox from './components/attributeCheckbox.vue';
  import { deepClone } from '/@/utils/common';

  interface stateModel {
    current: number;
    productParameter: object[] | any;
    productAttributes: object[] | any;
    fileList: object[] | any;
    modelParams: object | any;
    basicValue: object | any;
    parameterValue: object[] | any;
    attributesValue: object[] | any;
    pictureList: object[] | any;
    tinymce: string;
  }

  const shopGoodsStore = useShopGoodsStore();

  let schemas: any = ref([
    {
      field: 'goods_name',
      component: 'Input',
      label: '商品名称',
      componentProps: {
        placeholder: '请输入商品名称',
      },
      required: true,
    },
    {
      field: 'goods_price',
      component: 'InputNumber',
      label: '商品价格',
      componentProps: {
        placeholder: '请输入商品价格',
        style: 'width: 100%',
        min: 0,
      },
      required: true,
    },
    {
      field: 'goods_weight',
      component: 'InputNumber',
      label: '商品重量',
      componentProps: {
        placeholder: '请输入商品重量',
        style: 'width: 100%',
        min: 0,
      },
      required: true,
    },
    {
      field: 'goods_number',
      component: 'InputNumber',
      label: '商品数量',
      componentProps: {
        placeholder: '请输入商品数量',
        style: 'width: 100%',
        min: 0,
      },
      required: true,
    },
    {
      field: 'goods_cat',
      component: 'Cascader',
      label: '商品分类',
      componentProps: {
        placeholder: '请选择商品分类',
        options: [],
        expandTrigger: 'hover',
        onChange: (value: any) => {
          getCategoryAttributes('many', value);
          getCategoryAttributes('only', value);
        },
      },
      required: true,
    },
  ]);

  const useFormParams = ref({
    labelCol: {
      span: 8,
    },
    wrapperCol: {
      span: 10,
    },
    schemas: [],
    showActionButtonGroup: false,
  });

  const props = defineProps({
    type: String,
    id: Number,
  });

  const emits = defineEmits(['setEditStatus', 'getAddRow', 'getUpdateRow']);

  const state: stateModel = reactive({
    current: 0,
    productParameter: [],
    productAttributes: [],
    fileList: [],
    modelParams: {
      previewVisible: false,
      previewImage: '',
    },

    // 添加商品参数
    basicValue: {},
    parameterValue: [],
    attributesValue: [],
    pictureList: [],
    tinymce: '',
  });
  // 返回列表
  const handleBack = () => {
    emits('setEditStatus', false);
  };
  // 步骤条current改变
  const handleChange = async (_current: number) => {
    if (state.current != 0) {
      verifyBasic();
    }
  };
  // 底部上下步按钮
  const setCurrent = async (type: string) => {
    if (type == 'next') {
      state.current++;
    }
    if (type == 'pre') {
      state.current--;
    }
    if (state.current != 0) {
      verifyBasic();
    }
  };
  // 获取分类信息
  const getCategory = async () => {
    try {
      const data = await shopGoodsStore.getCategoryList({ resultType: 'tree' });
      schemas.value.forEach((item: any) => {
        if (item.field == 'goods_cat') {
          item.componentProps.options = data;
        }
      });
    } catch (error) {
      console.error(error);
    }
  };
  // 验证基本信息
  const verifyBasic = async () => {
    try {
      await validate();
    } catch (error) {
      console.error(error);
      message.warn('必填项不能为空');
      state.current = 0;
    }
  };
  // 获取分类参数
  const getCategoryAttributes = async (type: string, value: number[]) => {
    try {
      if (value.length != 3) throw Promise.reject('分类ID不存在');
      const str = value.join(',');
      const catId = parseInt(str.slice(-1)[0]);
      if (type == 'many') {
        const data = await shopGoodsStore.getCategoryAttributeList({ id: catId, sel: type });
        state.productParameter = data;
        state.parameterValue = data.map((item: any) => {
          return {
            attr_id: item.attr_id,
            attr_value: item.attr_vals.join(','),
          };
        });
      }
      if (type == 'only') {
        const data = await shopGoodsStore.getCategoryAttributeList({ id: catId, sel: type });
        state.productAttributes = data;
        useFormParams.value.schemas = data.map((item: any, _index: number) => {
          return {
            field: `${item.attr_id}`,
            component: 'Input',
            label: item.attr_name,
            defaultValue: item.attr_vals[0],
          };
        });
      }
      return Promise.resolve(true);
    } catch (error) {
      console.error(error);
    }
  };
  // 获取商品参数
  const getCheckbox = async (value: any) => {
    state.parameterValue.forEach((item: any) => {
      if (item.attr_id == value.attr_id) {
        item.attr_value = value.attr_value;
      }
    });
  };
  // 上传
  const handleAction = async (info: any) => {
    try {
      const { file } = info;
      const data = await shopGoodsStore.upload({ file }, ({ percent }) => {
        info.onProgress({ percent }, file);
      });
      state.pictureList.push({ pic: data.tmp_path });
      message.success('上传成功');
      info.onSuccess(data, file);
    } catch (error) {
      console.error(error);
      info.onError('上传失败');
    }
  };
  // 移除上传文件
  const handleRemove = (file: any) => {
    const toRawUploadList = toRaw(state.pictureList);
    if (file.response.tmp_path) {
      state.pictureList = toRawUploadList.filter((item: any) => {
        return item.pic != file.response.tmp_path;
      });
      return Promise.resolve('删除成功');
    } else {
      return Promise.reject('删除上传文件失败');
    }
  };
  // 图片预览
  const handlePreview = (file: any) => {
    state.modelParams.previewVisible = true;
    state.modelParams.previewImage = file.thumbUrl;
  };
  const handleModelCancel = () => {
    state.modelParams.previewVisible = false;
  };
  // 新增
  const addProduct = async (params: any) => {
    try {
      const data = await shopGoodsStore.addProduct(params);
      emits('getAddRow', data);
      message.success('添加商品成功');
    } catch (error) {
      console.error(error);
    }
  };
  // 提交
  const submitProduct = async () => {
    const { basicValue, parameterValue, attributesValue, pictureList, tinymce } = state;
    const params = {
      attrs: [...toRaw(parameterValue), ...toRaw(attributesValue)],
      pics: [...toRaw(pictureList)],
      goods_introduce: tinymce,
      ...toRaw(basicValue),
    };
    if (!props.type) {
      addProduct(params);
    } else {
      console.info('editSubmit');
      params.id = props.id;
      console.log(params);
      try {
        const data = await shopGoodsStore.updateProduct(params);
        message.success('修改信息成功');
        emits('getUpdateRow', data);
      } catch (error) {
        console.error(error);
      }
    }
  };

  // 获取单个商品信息
  const getSingleInfo = async () => {
    const {
      goods_name,
      goods_price,
      goods_number,
      goods_weight,
      goods_cat,
      goods_introduce,
      parameterValue,
      attributesValue,
      pics,
    } = shopGoodsStore.$state.singleProduct;
    const categories = toRaw(goods_cat);
    const catArr: number[] = [];
    categories.forEach((_item: any) => {
      catArr.push(parseInt(_item));
    });
    setFieldsValue({
      goods_name,
      goods_price,
      goods_number,
      goods_weight,
      goods_cat: catArr,
    });
    await getCategoryAttributes('many', catArr);
    await getCategoryAttributes('only', catArr);
    state.productParameter = parameterValue.reverse();
    state.parameterValue = parameterValue.map((item: any) => {
      return {
        attr_id: item.attr_id,
        attr_value: item.attr_value.join(','),
      };
    });
    const temp = {};
    state.attributesValue = attributesValue.map((item: any) => {
      temp[item.field] = item.defaultValue;
      return {
        attr_id: item.field,
        attr_value: item.defaultValue,
      };
    });
    attributesFn.setFieldsValue({ ...temp });
    pics.map((item: any) => {
      state.fileList.push({
        uid: item.pics_id,
        goods_id: item.goods_id,
        pics_id: item.pics_id,
        name: 'picture.png',
        status: 'done',
        url: `https://frontend-flk.site/bt-shopper${item.pics_mid}`,
        thumbUrl: `https://frontend-flk.site/bt-shopper${item.pics_mid}`,
      });
    });
    state.tinymce = goods_introduce;
  };

  watch(
    () => state.current,
    async (_current: number, prevCurrent) => {
      if (prevCurrent == 0) {
        const value = getFieldsValue();
        state.basicValue = deepClone(value);
        state.basicValue.goods_cat = state.basicValue.goods_cat.join(',');
      }
      if (prevCurrent == 2) {
        const attributesFieldsValue = attributesFn.getFieldsValue();
        state.attributesValue = Object.entries(attributesFieldsValue).map((item: any) => {
          return {
            attr_id: parseInt(item[0]),
            attr_value: item[1],
          };
        });
      }
    },
  );

  onMounted(() => {
    getCategory();
    if (props.type) {
      getSingleInfo();
    }
  });

  const [register, { validate, getFieldsValue, setFieldsValue }] = useForm({
    labelCol: {
      span: 8,
    },
    wrapperCol: {
      span: 10,
    },
    schemas: [...schemas.value],
    actionColOptions: {
      offset: 8,
      span: 12,
    },
    showActionButtonGroup: false,
  });

  const [attributesRegister, attributesFn] = useForm(useFormParams.value);
</script>

<style lang="less" scoped>
  .full-modal {
    :global(.ant-modal-content) {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    :global(.ant-modal-body) {
      flex: 1;
    }
  }
</style>
